﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;

namespace CmccTool.Services
{
    public static class FileHelper
    {
        #region 文件选择
        /// <summary>
        /// 打开文件选择对话框（单选）
        /// </summary>
        /// <param name="filter">文件过滤器（例："文本文件|*.txt|所有文件|*.*"）</param>
        /// <returns>选定文件的完整路径，未选择返回空字符串</returns>
        public static string SelectSingleFile(string filter = "所有文件|*.*")
        {
            using OpenFileDialog dialog = new();
            dialog.Filter = filter;
            dialog.Multiselect = false;
            return dialog.ShowDialog() == DialogResult.OK
                ? dialog.FileName
                : string.Empty;
        }

        /// <summary>
        /// 打开文件选择对话框（多选）
        /// </summary>
        /// <param name="filter">文件过滤器</param>
        /// <returns>选定文件的路径集合，未选择返回空集合</returns>
        public static List<string> SelectMultipleFiles(string filter = "所有文件|*.*")
        {
            using OpenFileDialog dialog = new();
            dialog.Filter = filter;
            dialog.Multiselect = true;
            return dialog.ShowDialog() == DialogResult.OK
                ? [.. dialog.FileNames]
                : [];
        }
        #endregion

        #region 文件信息获取
        /// <summary>
        /// 获取文件基础信息（名称、大小、路径等）
        /// </summary>
        /// <param name="filePath">文件完整路径</param>
        /// <returns>包含文件属性的字典，文件不存在时返回null</returns>
        public static Dictionary<string, object>? GetFileInfo(string filePath)
        {
            if (!File.Exists(filePath)) return null;

            FileInfo info = new(filePath);
            return new Dictionary<string, object>
        {
            { "Name", info.Name },
            { "FullName", info.FullName },
            { "SizeBytes", info.Length },
            { "SizeKB", info.Length / 1024.0 },
            { "SizeMB", info.Length / (1024.0 * 1024) },
            { "CreationTime", info.CreationTime },
            { "LastWriteTime", info.LastWriteTime },
            { "IsReadOnly", (info.Attributes & FileAttributes.ReadOnly) != 0 }
        };
        }

        /// <summary>
        /// 获取目录下所有文件信息（含子目录）
        /// </summary>
        /// <param name="directoryPath">目录路径</param>
        /// <param name="searchPattern">搜索模式（例："*.txt"）</param>
        /// <returns>文件信息字典列表</returns>
        public static List<Dictionary<string, object>> GetAllFilesInfo(string directoryPath, string searchPattern = "*.*")
        {
            var filesInfo = new List<Dictionary<string, object>>();
            try
            {
                foreach (string file in Directory.EnumerateFiles(directoryPath, searchPattern, SearchOption.AllDirectories))
                {
                    var fileInfo = GetFileInfo(file); // 先获取文件信息
                    if (fileInfo != null)             // 仅当非空时添加
                    {
                        filesInfo.Add(fileInfo);
                    }
                }
            }
            catch (Exception ex) when (ex is UnauthorizedAccessException || ex is DirectoryNotFoundException)
            {
                // 记录日志或抛出自定义异常
            }
            return filesInfo;
        }
        #endregion

        #region 文件操作
        /// <summary>
        /// 将文件转换为字节数组
        /// </summary>
        public static byte[] FileToBytes(string filePath)
        {
            try
            {
                return File.ReadAllBytes(filePath);
            }
            catch (IOException ex)
            {
                throw new InvalidOperationException("文件读取失败", ex);
            }
        }

        /// <summary>
        /// 将字节数组保存为文件
        /// </summary>
        public static void BytesToFile(byte[] data, string savePath)
        {
            try
            {
                File.WriteAllBytes(savePath, data);
            }
            catch (UnauthorizedAccessException)
            {
                throw new AccessViolationException("无权限写入目标路径");
            }
        }

        /// <summary>
        /// 复制目录（递归所有子内容）
        /// </summary>
        public static void CopyDirectory(string sourceDir, string targetDir)
        {
            // 防止父目录复制到子目录
            if (targetDir.StartsWith(sourceDir, StringComparison.OrdinalIgnoreCase))
                throw new ArgumentException("目标路径不能是源路径的子目录");

            Directory.CreateDirectory(targetDir);
            foreach (string file in Directory.GetFiles(sourceDir))
            {
                File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), true);
            }
            foreach (string subDir in Directory.GetDirectories(sourceDir))
            {
                CopyDirectory(subDir, Path.Combine(targetDir, new DirectoryInfo(subDir).Name));
            }
        }
        #endregion

        #region 辅助方法
        /// <summary>
        /// 安全删除文件（自动处理占用异常）
        /// </summary>
        public static bool SafeDelete(string filePath, int retryCount = 3)
        {
            for (int i = 0; i < retryCount; i++)
            {
                try
                {
                    File.Delete(filePath);
                    return true;
                }
                catch (IOException)
                {
                    System.Threading.Thread.Sleep(500); // 等待文件释放
                }
            }
            return false;
        }
        #endregion
    }
}
